﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using MyFramework.Command.Interfaces;

namespace MyFramework.Command.DelegateWatchCommand
{
    /// <summary>
    /// property watch multi
    /// </summary>
    public class PropertyWatchMulti : IPropertyWatchTail
    {
        #region Fields

        /// <summary>
        /// The chains
        /// </summary>
        private readonly List<PropertyWatchChain> chains;

        /// <summary>
        /// The source
        /// </summary>
        private INotifyPropertyChanged source;

        #endregion

        #region constructor

        /// <summary>
        /// Initializes a new instance of the <see cref="PropertyWatchMulti"/> class.
        /// </summary>
        /// <param name="chains">The chains.</param>
        public PropertyWatchMulti(IEnumerable<PropertyWatchChain> chains)
        {
            if (chains == null)
            {
                throw new ArgumentNullException("chains");
            }

            this.chains = chains.ToList();
            this.chains.ForEach(t => t.WatchedPropertyChanged += new EventHandler<EventArgs>(t_WatchedPropertyChanged));
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets the parent.
        /// </summary>
        /// <value>
        /// The parent.
        /// </value>
        public PropertyWatchChain Parent { get; set; }

        /// <summary>
        /// Gets or sets the source.
        /// </summary>
        /// <value>
        /// The source.
        /// </value>
        public INotifyPropertyChanged Source
        {
            get { return source; }
            set
            {
                if (source != value)
                {
                    source = value;
                    chains.ForEach(pw => pw.Head.Source = value);
                }
            }
        }

        #endregion

        #region Methods

        /// <summary>
        /// Clones this instance.
        /// </summary>
        /// <returns></returns>
        public IPropertyWatchTail Clone()
        {
            var ret = new PropertyWatchMulti(chains.Select(x => x.Clone()));
            return ret;
        }

        /// <summary>
        /// Gets the tail.
        /// </summary>
        /// <returns></returns>
        public IPropertyWatchTail GetTail()
        {
            return this;
        }

        /// <summary>
        /// Handles the WatchedPropertyChanged event of the t control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void t_WatchedPropertyChanged(object sender, EventArgs e)
        {
            if (this.Parent != null)
                this.Parent.OnWatchedPropertyChanged();
        }

        #endregion
    }
}
